#include "humidity.h"
#include "ui_humidity.h"

#include <fcntl.h>
#include <unistd.h>
#include <QDebug>
#include <sys/ioctl.h>
#include <QSocketNotifier>
#include <iostream>
#include <sys/time.h>
#include <QMessageBox> // 包含QMessageBox头文件
// #include "wifiserial.h"
QSerialPort *serial2 = nullptr;
#define BUZZER_IOCTL_SET_FREQ 1
#define BUZZER_IOCTL_STOP 0
#define KEY0 0 // 开始检测按键
#define KEY1 1 // 停止检测按键
#define KEY2 2 // 打开蜂鸣器按键
#define KEY3 3 // 关闭蜂鸣器按键
#define GEC6818_ADC_IN0 _IOR('A', 1, unsigned long)
#define GEC6818_ADC_IN1 _IOR('A', 2, unsigned long)

int beep_en; // 蜂鸣器使能
int id = 0;  // 编号
QString tmpData = "";
QString humData = "";
unsigned long lightData = 0;
unsigned int distanceData = 0;
double tem = 0.0;
double hum = 0.0;
Humidity::Humidity(QWidget *parent) : QWidget(parent),
                                      ui(new Ui::Humidity),
                                      titleLabel(new QLabel(this)),       // 初始化 titleLabel
                                      model(new QStandardItemModel(this)) // 初始化 model
{
    ui->setupUi(this);
    addTitleLabel();
    fd = -1;
    this->window = new SetTime; // 注册另外两个界面
    connect(serial2, SIGNAL(readyRead()), this, SLOT(readSerial2()));
    connect(window, &SetTime::goback, this, [=]()
            {window->close();this->show(); });
    this->window_1 = new Camera;
    connect(window_1, &Camera::goback, this, [=]()
            {window_1->close();this->show(); this->raise(); });
    this->window_2 = new WIFIserial;
    connect(window_2, &WIFIserial::goback, this, [=]()
            {window_2->close();this->show(); this->raise(); });

    pwm_fd = open("/dev/pwm", O_RDWR);
    if (pwm_fd < 0)
        qDebug("Failed to open beep dev!");
    key_fd = open("/dev/gecBt", O_RDONLY);
    if (key_fd < 0)
    {
        qDebug("Failed to open key dev!");
    }
    else
    {
        key_notifier = new QSocketNotifier(key_fd, QSocketNotifier::Read, this);
        connect(key_notifier, SIGNAL(activated(int)), this, SLOT(handleKeyPress()));
    }
    sr04_fd = open("/dev/sr04", O_RDONLY);
    if (sr04_fd < 0)
    {
        qDebug("Failed to open sr04 dev!");
    }
    light_fd = open("/dev/adc_drv", O_RDONLY);
    {
        qDebug("Failed to open adc");
    }
    if (light_fd < 0)
    {
        qDebug("Failed to open light dev!");
    }

    model = new QStandardItemModel(this);
    tableView = ui->tableView; // 获取QTableView的引用
    tableView->setModel(model);
    tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    tableView->setSelectionBehavior(QAbstractItemView::SelectRows);

    QStringList headers = {QObject::tr("编号"), QObject::tr("温度"), QObject::tr("湿度"),
                           QObject::tr("light"),
                           QObject::tr("距离"), QObject::tr("时间"), QObject::tr("ID"),
                           QObject::tr("地点")};
    model->setHorizontalHeaderLabels(headers);

    adjustTableViewColumns(); // 调整表格列宽
}
Humidity::~Humidity()
{
    // if (fd > 0)
    //     ::close(fd);
    if (pwm_fd > 0)
        ::close(pwm_fd);
    if (key_notifier)
    {
        delete key_notifier;
        ::close(key_fd);
    }
    if (sr04_fd > 0)
        ::close(sr04_fd);

    delete ui;
}
void Humidity::adjustTableViewColumns()
{
    // 设置列宽
    tableView->setColumnWidth(0, 60);
    tableView->setColumnWidth(1, 60);
    tableView->setColumnWidth(2, 80);
    tableView->setColumnWidth(3, 70);
    tableView->setColumnWidth(4, 100);
    tableView->setColumnWidth(5, 250);
    tableView->setColumnWidth(6, 50);
    tableView->setColumnWidth(7, 100);

    // 获取模型的表头项并设置表头文字
    QStandardItem *headerItem;
    headerItem = model->horizontalHeaderItem(0);
    if (headerItem)
        headerItem->setText(QObject::tr("编号"));

    headerItem = model->horizontalHeaderItem(1);
    if (headerItem)
        headerItem->setText(QObject::tr("温度"));

    headerItem = model->horizontalHeaderItem(2);
    if (headerItem)
        headerItem->setText(QObject::tr("湿度"));

    headerItem = model->horizontalHeaderItem(3);
    if (headerItem)
        headerItem->setText(QObject::tr("光照"));

    headerItem = model->horizontalHeaderItem(4);
    if (headerItem)
        headerItem->setText(QObject::tr("距离"));

    headerItem = model->horizontalHeaderItem(5);
    if (headerItem)
        headerItem->setText(QObject::tr("时间"));

    headerItem = model->horizontalHeaderItem(6);
    if (headerItem)
        headerItem->setText(QObject::tr("ID"));

    headerItem = model->horizontalHeaderItem(7);
    if (headerItem)
        headerItem->setText(QObject::tr("地点"));
    // 更新视图
    tableView->viewport()->update();
    tableView->update();
}
void Humidity::handleKeyPress()
{
    char key[4];
    memset(key, 0, 4);
    ::read(key_fd, key, sizeof(key));
    for (int i = 0; i < (int)sizeof(key); i++)
    {
        switch (i)
        {
        case KEY0: // 开始检测
            if (key[i] != '0')
            {
                if (!timer.isActive())
                {
                    std::cout << "Key1 pressed. Starting humidity and temperature monitoring." << std::endl;
                    QMessageBox::information(this, "Info", "开始监测湿度和温度.");
                    ui->pushButton->setText("停止获取");
                    connect(&timer, SIGNAL(timeout()), this, SLOT(slt_timeout()));
                    timer.start(2000);
                }
                ui->pushButton->setStyleSheet("background:red");
            }
            else
                ui->pushButton->setStyleSheet("background:gray");
            break;

        case KEY1: // 停止检测
            if (key[i] != '0')
            {
                if (timer.isActive())
                {
                    timer.stop();
                    std::cout << "Key2 pressed. Stopping humidity and temperature monitoring." << std::endl;
                    QMessageBox::information(this, "Info", "停止监测湿度和温度.");
                    ui->pushButton->setText("获取");
                    if (pwm_fd > 0)
                    {
                        ::ioctl(pwm_fd, BUZZER_IOCTL_STOP, 0);
                    }
                }
                ui->pushButton->setStyleSheet("background:red");
            }
            else
                ui->pushButton->setStyleSheet("background:gray");
            break;

        case KEY2: // 按键清除数据
            if (key[i] != '0')
            {
                QMessageBox::information(this, "Info", "按键错误.");
            }
            break;
        case KEY3: // 按键错误
            if (key[i] != '0')
            {
                QMessageBox::information(this, "Info", "按键错误.");
            }
            break;

        default:
            if (key[i] != '0')
            {
                std::cout << "Key press error." << std::endl;
            }
            break;
        }
    }
}

void Humidity::addTitleLabel()
{
    titleLabel->setText("QT温湿度检测_唐傲宇");
    titleLabel->setGeometry(180, 10, 400, 35); // 设置标签的位置和大小
    titleLabel->setFont(QFont("Arial", 20));   // 设置字体和大小
}

void Humidity::on_pushButton_clicked()
{
    // if (fd < 0)
    //     return;

    if (timer.isActive())
    {
        timer.stop();
        ui->pushButton->setText("获取");
        if (pwm_fd > 0)
        {
            ::ioctl(pwm_fd, BUZZER_IOCTL_STOP, 0);
        }
    }
    else
    {
        beep_en = 1;
        ui->pushButton->setText("停止获取");
        connect(&timer, SIGNAL(timeout()), this, SLOT(slt_timeout()));
        timer.start(2000);
        serial2->write("Auto\r\n");
    }
}

void Humidity::on_pushButton_2_clicked()
{
    // if (fd < 0)
    //     return;
    if (beep_en == 0)
    {
        beep_en = 1;
        ui->pushButton_2->setText("停止蜂鸣器");
    }
    else
    {
        beep_en = 0;
        ui->pushButton_2->setText("打开蜂鸣器");
    }
}

void Humidity::slt_timeout()
{
    disconnect(&timer, SIGNAL(timeout()), this, SLOT(slt_timeout()));
    readSerial2();

    unsigned int distance;
    unsigned long adc_value; // 用于存储ADC值
    int ret;

    // light
    ret = ::ioctl(light_fd, GEC6818_ADC_IN0, &adc_value);

    unsigned long percentage = 100 - (adc_value / 40);
    lightData = percentage;
    // int light_show = percentage;
    //  读取距离数据
    if (sr04_fd >= 0)
    {
        if (::read(sr04_fd, &distance, sizeof(distance)) == sizeof(distance))
        {
            // 成功读取距离数据
            distanceData = distance;
        }
        else
        {
            // 读取失败，可以设置一个默认值或者跳过
            distance = 0;
        }
    }
    else
    {
        // 4 设备文件未打开，可以设置一个默认值或者跳过
        distance = 0;
    }
    // 获取当前时间
    struct timeval tv;
    gettimeofday(&tv, NULL);
    struct tm tm;
    localtime_r(&tv.tv_sec, &tm);
    char time_str[50];
    strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &tm);
    // 将新的温湿度数据添加到QListWidget中

    adjustTableViewColumns();
    this->window = new SetTime;
    connect(window, &SetTime::goback, this, [=]()
            {window->close();this->show(); });

    int row = model->rowCount();
    model->insertRow(row);

    id++;
    QStandardItem *idItem = new QStandardItem(QString::number(id));
    QStandardItem *tempItem = new QStandardItem(QString::number(hum));
    QStandardItem *humidItem = new QStandardItem(QString::number(tem) + "°C");
    QStandardItem *light = new QStandardItem(QString::number(percentage));
    QStandardItem *distItem = new QStandardItem(QString::number(distance) + "cm");

    QStandardItem *timeItem = new QStandardItem(QString(time_str));
    QStandardItem *statusItem = new QStandardItem("223");
    QStandardItem *locationItem = new QStandardItem("十三教");

    model->setItem(row, 0, idItem);
    model->setItem(row, 1, tempItem);
    model->setItem(row, 2, humidItem);
    model->setItem(row, 3, light);
    model->setItem(row, 4, distItem);
    model->setItem(row, 5, timeItem);
    model->setItem(row, 6, statusItem);
    model->setItem(row, 7, locationItem);

    // std::cout << "light"<<percentage<< ", Humidity: " << hum_value.toStdString() << ", Temperature: " << temp_value.toStdString() << ", Distance: " << distance << ", Time: " << time_str << std::endl;
    std::cout << 'hum:' << hum << ",tem:" << tem << ",light:" << percentage << ',distance:' << distance << std::endl;

    // 检查温度是否大于20
    if (beep_en == 1)
    {
        // 设置蜂鸣器频率
        if (tem > 30 || distance < 50)
            ::ioctl(pwm_fd, BUZZER_IOCTL_SET_FREQ, 3000); // 假设3000Hz为蜂鸣器的频率
        else
        {
            // 停止蜂鸣器
            ::ioctl(pwm_fd, BUZZER_IOCTL_STOP, 0);
        }
    }
    else
    {
        // 停止蜂鸣器
        ::ioctl(pwm_fd, BUZZER_IOCTL_STOP, 0);
    }

    connect(&timer, SIGNAL(timeout()), this, SLOT(slt_timeout()));
}

void Humidity::on_setT_clicked()
{

    this->hide();
    window->show(); // 显示第二个
}

void Humidity::on_gocamera_clicked()
{
    this->hide();
    window_1->show(); // 显示第3个
    showflag = true;
}

void Humidity::on_setWIFI_clicked()
{
    this->hide();
    window_2->show(); // 显示第4个
}
void Humidity::readSerial2()
{
    // 读取所有可用的数据
    QByteArray data = serial2->readAll();
    if (!data.isEmpty())
    {
        QString strData = QString::fromLocal8Bit(data);
        int indexR = strData.indexOf("R:");
        int indexRH = strData.indexOf("RH");
        int indexC = strData.indexOf("C");

        if (indexR != -1 && indexRH != -1 && indexC != -1)
        {
            // 提取温度和湿度字符串
            tmpData = strData.mid(indexR + 2, indexRH - indexR - 2);
            humData = strData.mid(indexRH + 2, indexC - indexRH - 2);

            // 转换为数值，保留小数
            tem = tmpData.toDouble();
            hum = humData.toDouble();
        }
    }
}